package com.zhu.tool_test.handler;

import core.Data;
import core.MultipartData;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: tool_test
 * @description: 利用 ResponseBodyAdvice 统一返回值
 * @author: ggBall
 * @create: 2020-12-14 16:49
 **/
@RestControllerAdvice(basePackages = "com.zhu.tool_test.controller")
public class ControllerResHandler implements ResponseBodyAdvice<Object> {
    /**
     * Whether this component supports the given controller method return type
     * and the selected {@code HttpMessageConverter} type.
     *
     * @param returnType    the return type
     * @param converterType the selected converter type
     * @return {@code true} if {@link #beforeBodyWrite} should be invoked;
     * {@code false} otherwise
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        RequestMapping methodAnnotation = returnType.getMethodAnnotation(RequestMapping.class);
        RequestMethod[] method = methodAnnotation.method();
        // 如果接口是查询接口 才拦截
        for (RequestMethod requestMethod : method) {
            if (RequestMethod.GET.equals(requestMethod)) {
                return true;
            }
        }

        System.out.println("methodAnnotation = " + methodAnnotation);
        System.out.println("returnType = " + returnType);
        System.out.println("converterType = " + converterType);
        return false;
    }

    /**
     * Invoked after an {@code HttpMessageConverter} is selected and just before
     * its write method is invoked.
     *
     * @param body                  the body to be written
     * @param returnType            the return type of the controller method
     * @param selectedContentType   the content type selected through content negotiation
     * @param selectedConverterType the converter type selected to write to the response
     * @param request               the current request
     * @param response              the current response
     * @return the body that was passed in or a modified (possibly new) instance
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        Data result = (Data) body;
        List<MultipartData> dataList = result.getListPart("data", MultipartData.class);
        String data = result.getStringPart("data");

        if ((null == dataList || dataList.size() == 0) && ("".equals(data) || null == data)) {
            result.include("msg","数据为空");
            result.include("code","400");
            result.remove("data");
        }
        return result;
    }

    /**
    * @Description 全局异常捕获
    * @Author  ggBall
    * @Date   2020/12/14 18:13
    * @Param
     * @param ex
    * @Return      java.util.Map
    * @Exception
    *
    */
    @ExceptionHandler(value = Exception.class)
    public Map myErrorHandler(Exception ex) {
        Map map = new HashMap();
        map.put("code", 500);
        map.put("msg", ex.getMessage());
        return map;
    }

}
